﻿using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using WhatCatch.Core2.Model;

namespace WhatCatch.Core2
{
    public class HtmlAnalyser : IHtmlAnalyser
    {
        

        public List<string> AnalyserList(AnalyserContextRequest context)
        {
            //解析页面
            HtmlDocument htmlDoc = new HtmlDocument();
            htmlDoc.OptionAutoCloseOnEnd = true;
            htmlDoc.LoadHtml(context.Html);
            //requestContext.HtmlDocument = htmlDoc;

            //列表区域
            HtmlNode contentNode = null;
            if (!string.IsNullOrEmpty(context.Task.Config.ListXPath))
            {
                contentNode = htmlDoc.DocumentNode.SelectSingleNode(context.Task.Config.ListXPath);
            }
            else
            {
                contentNode = htmlDoc.DocumentNode;
            }
            //requestContext.ListHtml = contentNode.OuterHtml;

            //列表项
            HtmlNodeCollection listNode = null;
            if (string.IsNullOrEmpty(context.Task.Config.ListItemXPath))//未指定xpath
            {
                listNode = contentNode.SelectNodes("descendant::div|descendant::li|descendant::tr");

                var listItemUrl = new List<string>();

                return listItemUrl;
            }
            else//指定xpath
            {
                listNode = contentNode.SelectNodes(context.Task.Config.ListItemXPath);
                if (listNode == null)
                {
                    throw new Exception("找不到项");
                }

                var listItemUrl = new List<string>();
                foreach (var item in listNode)
                {
                    var url = GetUrl(item.OuterHtml, context.Url);
                    listItemUrl.Add(url);
                }
                //requestContext.ItemUrls = listItemUrl;
                return listItemUrl;
            }
        }

        public List<string> AnalyserPage(AnalyserContextRequest context)
        {
            //解析页面
            HtmlDocument htmlDoc = new HtmlDocument();
            htmlDoc.OptionAutoCloseOnEnd = true;
            htmlDoc.LoadHtml(context.Html);
            //requestContext.HtmlDocument = htmlDoc;

            //分页区域
            HtmlNode contentNode = null;
            if (!string.IsNullOrEmpty(context.Task.Config.PageXPath))
            {
                contentNode = htmlDoc.DocumentNode.SelectSingleNode(context.Task.Config.PageXPath);
            }
            else
            {
                contentNode = htmlDoc.DocumentNode;
            }
            //requestContext.PageHtml = contentNode.OuterHtml;

            //列表项
            HtmlNodeCollection listPageNode = null;
            if (string.IsNullOrEmpty(context.Task.Config.PageItemXPath))//未指定xpath
            {
                listPageNode = contentNode.SelectNodes("descendant::div|descendant::li|descendant::tr|descendant::a");

                var listPageItemUrl = new List<string>();

                return listPageItemUrl;
            }
            else//指定xpath
            {
                listPageNode = contentNode.SelectNodes(context.Task.Config.PageItemXPath);
                if (listPageNode == null)
                {
                    throw new Exception("找不到分页项");
                }

                var listPageItemUrl = new List<string>();
                foreach (var item in listPageNode)
                {
                    var url = GetPageUrl(item.OuterHtml, context.Url);
                    listPageItemUrl.Add(url);
                }
                //requestContext.PageUrls = listPageItemUrl;
                return listPageItemUrl;
            }
        }

        public ContentResponse AnalyserContent(AnalyserContextRequest context)
        {
            //解析页面
            HtmlDocument htmlDoc = new HtmlDocument();
            htmlDoc.OptionAutoCloseOnEnd = true;
            htmlDoc.LoadHtml(context.Html);
            //requestContext.HtmlDocument = htmlDoc;

            //分页区域
            HtmlNode contentNode = null;
            if (!string.IsNullOrEmpty(context.Task.Config.DetailXPath))
            {
                contentNode = htmlDoc.DocumentNode.SelectSingleNode(context.Task.Config.DetailXPath);
            }
            else
            {
                contentNode = htmlDoc.DocumentNode;
            }

            ContentResponse response = new ContentResponse();
            if (!string.IsNullOrEmpty(context.Task.Config.DetailTitleXPath))//未指定xpath
            {
                var titleNode = contentNode.SelectSingleNode(context.Task.Config.DetailTitleXPath);
                //titleNode.InnerText
                response.Title = titleNode.InnerText;
            }
            return response;

        }

        private string GetUrl(string txt, string baseUrl)
        {

            var mcs = new Regex(@"<a[^>]*?>(?<title>[\s\S]*?)</a>", RegexOptions.IgnoreCase).Matches(txt);
            string title = "";
            foreach (Match mc in mcs)
            {
                title = mc.Groups["title"].Value;
                if (title == "" || title.Length <= 4 || title.Contains("<div") || title.Contains("<img"))
                {
                    continue;
                }
                else
                {
                    var mc2 = new Regex(@"<a[^>]+href=\s*(?:'(?<href>[^']+)'|""(?<href>[^""]+)""|(?<href>[^>\s]+))\s*[^>]*>(?<text>.*?)</a>", RegexOptions.IgnoreCase | RegexOptions.Singleline).Match(mc.Value);
                    string url = "";
                    if (mc2.Success)
                    {
                        url = mc2.Groups["href"].Value;
                        url = HandleUrl(baseUrl, url);
                    }
                    return url;
                }
            }
            return "-1";
        }

        private string GetPageUrl(string txt, string baseUrl)
        {
            var matches = new Regex(@"<a[^>]+href=\s*(?:'(?<href>[^']+)'|""(?<href>[^""]+)""|(?<href>[^>\s]+))\s*[^>]*>(?<text>.*?)</a>", RegexOptions.IgnoreCase | RegexOptions.Singleline).Matches(txt);
            foreach (Match m in matches)
            {
                string url = m.Groups["href"].Value;
                url = HandleUrl(baseUrl, url);

                url = url.Replace("&amp;", "&");

                if (url.IndexOf("script") >= 0)
                {
                    continue;
                }

                return url;
            }
            return "";
        }

        private string HandleUrl(string baseUrl, string url)
        {
            if (!string.IsNullOrEmpty(baseUrl))
            {
                Uri baseUri = new Uri(baseUrl);
                Uri absoluteUri = new Uri(baseUri, url);//相对绝对路径都在这里转 这里的urlx ="../test.html"
                return absoluteUri.ToString();
            }
            else
            {
                return url;
            }
        }
    }
}
